package com.wk.pms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.wk.common.bean.PageVo;
import com.wk.common.bean.Query;
import com.wk.common.bean.QueryCondition;
import com.wk.common.constant.mq.ItemExchange;
import com.wk.common.constant.mq.ItemRoutingKey;
import com.wk.pms.entity.*;
import com.wk.pms.mapper.SkuInfoMapper;
import com.wk.pms.mapper.SpuInfoDescMapper;
import com.wk.pms.mapper.SpuInfoMapper;
import com.wk.pms.service.ProductAttrValueService;
import com.wk.pms.service.SkuImagesService;
import com.wk.pms.service.SkuSaleAttrValueService;
import com.wk.pms.service.SpuInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wk.pms.vo.BaseAttrVO;
import com.wk.pms.vo.SkuInfoVO;
import com.wk.pms.vo.SpuInfoVO;
import com.wk.sms.feign.SkuBoundsFeign;
import com.wk.sms.vo.SkuSaleVO;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoMapper, SpuInfo> implements SpuInfoService {

    @Autowired
    private SpuInfoDescMapper descMapper;

    @Autowired
    private ProductAttrValueService valueService;

    @Autowired
    private SkuInfoMapper skuInfoMapper;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private SkuSaleAttrValueService saleAttrService;

    @Autowired
    private SkuBoundsFeign skuBoundsFeign;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public PageVo querySpuPage(QueryCondition condition, Long categoryId) {
        String key = condition.getKey();

        IPage<SpuInfo> page = baseMapper.selectPage(
                new Query<SpuInfo>().getPage(condition),
                new QueryWrapper<SpuInfo>()
                        .eq(categoryId != 0, "catalog_id", categoryId)
                        //and (id=#{key} or spu_name=#{key})
                        .nested(StringUtils.isNotBlank(key),
                                i -> i.eq("id", key)
                                        .or()
                                        .like("spu_name", key)));
        return new PageVo(page);
    }

    /**
     * 新增spu、sku和营销信息
     */
    @GlobalTransactional
    @Override
    public void saveSpuInfo(SpuInfoVO spuInfoVo) {

        //保存spu相关的3张表
        insertSpuInfo(spuInfoVo);
        Long spuId = spuInfoVo.getId();


        //保存数据到sku和营销信息相关表
        insertSkuInfoAndSms(spuInfoVo,spuId);

        //商品添加后发送spuId到消息队列 用于更新ES索引库
        amqpTemplate.convertAndSend(ItemExchange.PMS_EXCHANGE, ItemRoutingKey.ITEM_INSERT,spuId);
    }

    @Override
    public void updateOne(SpuInfo spuInfo) {
        baseMapper.updateById(spuInfo);
        //spu修改数据后将spuId发送到队列中 购物车微服务监听并更新购物车中商品的价格
        amqpTemplate.convertAndSend(ItemExchange.PMS_EXCHANGE,ItemRoutingKey.ITEM_UPDATE,spuInfo.getId());
    }


    //保存数据到sku和营销信息相关表
    private void insertSkuInfoAndSms(SpuInfoVO spuInfoVo, Long spuId) {
        List<SkuInfoVO> skus = spuInfoVo.getSkus();
        if (CollectionUtils.isEmpty(skus)) {
            return;
        }

        //存放商品基本信息 用于保存sale_attr_value的attrName属性
        Map<Long,String> attrMap = new HashMap<>();
        spuInfoVo.getBaseAttrs().forEach(attr->{
            attrMap.put(attr.getAttrId(), attr.getAttrName());
        });

        skus.forEach(sku->{
            //保存sku相关的3张表
            insertSkuInfo(spuInfoVo, spuId, sku, attrMap);

            //保存数据到营销信息相关表
            SkuSaleVO skuSaleVo = new SkuSaleVO();
            BeanUtils.copyProperties(sku, skuSaleVo);
            skuSaleVo.setSkuId(sku.getSkuId());
            skuBoundsFeign.saveSaleAttr(skuSaleVo);
        });
    }

    //保存sku相关的3张表
    private void insertSkuInfo(SpuInfoVO spuInfoVo, Long spuId, SkuInfoVO sku,Map<Long,String> attrMap) {
        //1.sku_info表
        sku.setSpuId(spuId);
        sku.setSkuCode(UUID.randomUUID().toString());
        sku.setCatalogId(spuInfoVo.getCatalogId());
        sku.setBrandId(spuInfoVo.getBrandId());
        sku.setImages(spuInfoVo.getSpuImages());
        //设置sku默认图片
        List<String> images = sku.getImages();
        if(!org.springframework.util.CollectionUtils.isEmpty(images)){
            //默认图片不为空用默认图片,为空用图片集合的第一张图片
            sku.setSkuDefaultImg(StringUtils.isNotBlank(sku.getSkuDefaultImg())?sku.getSkuDefaultImg():images.get(0));
        }
        skuInfoMapper.insert(sku);

        //2.sku_images表
        Long skuId = sku.getSkuId();
        //将图片路径设置到对象中
        if (CollectionUtils.isNotEmpty(images)) {
            List<SkuImages> imagesList = images.stream().map(image -> {
                SkuImages skuImages = new SkuImages();
                skuImages.setSkuId(skuId);
                skuImages.setImgUrl(image);
                //设置默认图片;如果当前图片和默认图片一样就是默认图片,1:默认
                skuImages.setDefaultImg(StringUtils.equals(sku.getSkuDefaultImg(), image) ? 1 : 0);
                return skuImages;
            }).collect(Collectors.toList());
            skuImagesService.saveBatch(imagesList);
        }

        //3.sale_attr_value销售属性
        List<SkuSaleAttrValue> saleAttrs = sku.getSaleAttrs();

        if (CollectionUtils.isNotEmpty(saleAttrs)) {
            //设置skuid
            saleAttrs.forEach(saleAttr->{
                saleAttr.setSkuId(skuId);
                saleAttr.setAttrName(attrMap.get(saleAttr.getAttrId()));
            });
            //批量保存销售属性
            saleAttrService.saveBatch(saleAttrs);
        }
    }

    //保存spu相关的3张表
    private void insertSpuInfo(SpuInfoVO spuInfoVo) {
        LocalDateTime now = LocalDateTime.now();
        spuInfoVo.setCreateTime(now);
        spuInfoVo.setUpdateTime(now);
        //1.spu_info表
        baseMapper.insert(spuInfoVo);
        Long spuId = spuInfoVo.getId();

        //2.spu_info_desc表
        List<String> spuImages = spuInfoVo.getSpuImages();
        if (CollectionUtils.isNotEmpty(spuImages)) {
            SpuInfoDesc spuInfoDesc = new SpuInfoDesc();
            spuInfoDesc.setSpuId(spuId);
            //spu商品描述,一般用图片表示
            spuInfoDesc.setDecript(StringUtils.join(spuImages, ","));
            descMapper.insert(spuInfoDesc);
        }

        //3.product_attr_value表
        List<BaseAttrVO> baseAttrs = spuInfoVo.getBaseAttrs();
        if (CollectionUtils.isNotEmpty(baseAttrs)) {

            //将集合中的BaseAttrVo对象强转成ProductAttrValue对象
            List<ProductAttrValue> valueList = baseAttrs.stream().map(baseAttrVO -> {
                baseAttrVO.setSpuId(spuId);
                return (ProductAttrValue) baseAttrVO;
            }).collect(Collectors.toList());

            valueService.saveBatch(valueList);
        }

    }
}
